<!-- 代码编辑器 -->
<template>
    <div
        ref="monacoRef"
        v-loading="loading"
        element-loading-text="加载中..."
        :style="{ width, height }"
    ></div>
</template>

<script>
import { defineComponent, toRefs, ref, onMounted, onUnmounted } from 'vue'
import { isDark } from '@/libs/dark'
import { deepClone } from '@/libs/tools'

// 代码格式化/美化
import { js_beautify } from 'js-beautify'

// 代码编辑器
// import * as monaco from 'monaco-editor'
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'
// import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker'
// import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker'
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'

import useJavascriptCompletion from './javascript-completion'

// 解决vite Monaco提示错误
self.MonacoEnvironment = {
    getWorker(_, label) {
        if (label === 'json') {
            return new jsonWorker()
        }
        // if (label === 'css' || label === 'scss' || label === 'less') {
        //   return new cssWorker()
        // }
        // if (label === 'html' || label === 'handlebars' || label === 'razor') {
        //   return new htmlWorker()
        // }
        if (label === 'typescript' || label === 'javascript') {
            return new tsWorker()
        }
        return new editorWorker()
    }
}

export default defineComponent({
    name: 'MonacoEditor',
    props: {
        width: {
            type: String,
            default: '100%'
        },
        height: {
            type: String,
            default: '100%'
        }
    },
    setup(props, { attrs }) {
        const { width, height } = toRefs(props)

        const monacoRef = ref(null)
        const loading = ref(false)
        let monacoEditor = null
        let monacoProvider = null

        onMounted(async () => {
            loading.value = true
            // 代码编辑器(动态引入，把monaco-editor独立打包出来，不占用主包的体积)
            const monaco = await import('monaco-editor')

            const {
                javascriptCompletion
            } = useJavascriptCompletion(monaco)

            // 创建编辑器
            monacoEditor = monaco.editor.create(monacoRef.value, {
                // value: '', // 编辑器初始显示文字
                // language: 'json', // 语言支持(json，javascript),更多自行查阅demo
                automaticLayout: true,  // 自动布局
                theme: isDark.value ? 'vs-dark' : 'vs', // 官方自带三种主题 vs, hc-black, or vs-dark
                ...attrs,
                value: js_beautify(deepClone(attrs.value))
            })

            // 创建代码提示
            monacoProvider = javascriptCompletion

            loading.value = false
        })

        onUnmounted(() => {
            monacoEditor.dispose()
            monacoProvider.dispose()
            monacoEditor = null
            monacoProvider = null
        })

        const getValue = () => {
            return monacoEditor.getValue()
        }

        return {
            width,
            height,
            monacoRef,
            loading,

            getValue
        }
    }
})
</script>